﻿/**
* Replacement for AS2 Delegate 
* 
* Useful for making callbacks with extra args.
* see http://wildwinter.blogspot.com/2007/04/come-back-delegate-all-is-forgiven.html* 
* 
* (c) 2007 Ian Thomas
* Freely usable in whatever way you like, as long as it's attributed.
* 
* Original by Ian Thomas, Modified by David Knape
* - fixed some things in original
* - added callLater method for delayed delegates
* 
* @author Ian Thomas
* @author David Knape 
* @version 0.2
*	
*	used w/o permission
*/

package com.hatch.utils {        
    
    import flash.utils.Timer;
    import flash.events.TimerEvent;	    
    import flash.utils.Dictionary;
    
    public class Delegate
	{               
	    
	     // Create a wrapper for a callback function.
        // Tacks the additional args on to any args normally passed to the
        // callback.
    	public static function create(handler:Function,...args):Function
    	{
    		return function(...innerArgs):void
    		{
    			var handlerArgs:Array = [];
    			if(innerArgs!=null) handlerArgs = innerArgs;
    			if(args!=null) handlerArgs = handlerArgs.concat( args );
    			handler.apply(this, handlerArgs);
    		};
    	}
    	
    	public static function callLater(delayMs:int, handler:Function, ...args) : Timer {
            var timer:Timer = new Timer( delayMs, 1 );   
            var d:Function = Delegate.create( afterDelay, handler, args );            
            timerDelegates[timer] = d;                     
            timer.addEventListener(TimerEvent.TIMER_COMPLETE, d);
            timer.start(); 
            
            return timer;
        }  
        
        private static function afterDelay( e:TimerEvent, handler:Function, args:Array ) : void {
            handler.apply( null, args );
            cancel( e.target as Timer );  
        }
        
        public static function cancel( timer:Timer ) : void {
        	if(timer!=null) {                	    
        	    timer.reset();               	                   
        	    if(timerDelegates[timer]!=null) {
        	        timer.removeEventListener( TimerEvent.TIMER_COMPLETE, timerDelegates[timer] ); 
        	    	delete timerDelegates[timer];
        	    }
            }
        }          
        
        static private var timerDelegates:Dictionary = new Dictionary( true );
	    
	    
        
    }
	
}
